/***************************************
 ***                                 ***
 ***                                 ***
 ***                                 ***
 ***************************************/

 
/** InputForm [静态类页面 获取 / 渲染 数据] */
let InputFormInterface = (function(){
    // 全局初始化标识
    let InitSign = new Object;
    // 类的内部方法
    let PrivateClass = {
        description: 'This Method For Private Method For Class',
        ParentBackUp: new Object,
        RenderingBackUp: new Object,
        /**
         * [ControlModel HTML 控件, 获取器 (页面渲染主控件)]
         * @Author   SEven
         * @DateTime 2019-01-31
         */
        ControlModel: function (MainCtrlName = false){
            let MainCtrl = false;
            if(typeof MainCtrlName === 'string'){
                MainCtrl = document.getElementsByClassName(MainCtrlName);
                MainCtrl = MainCtrl.length === 0 ? document.getElementById(MainCtrlName ,true) : MainCtrl;

                if(MainCtrl.length > 1){
                    console.error('Conversion Form Error :Too Much Element By < ' + MainCtrlName + ' >');
                    return false;
                }
                if(MainCtrl instanceof HTMLCollection){
                    MainCtrl = MainCtrl[0] === undefined ? false : MainCtrl[0];
                }
            }else if(MainCtrlName instanceof HTMLElement){
                MainCtrl = MainCtrlName
            }

            if(MainCtrl === false){
                console.error('Conversion Form Error :Not Found Element By < ' + MainCtrlName + ' >');
                return false;
            }
    
            if(InitSign[MainCtrlName] === undefined){
                // 保存 [渲染控件] 父级元素
                PrivateClass.ParentBackUp[MainCtrlName] = MainCtrl;
                // 保存 [渲染控件] 模板元素 <复制>
                PrivateClass.RenderingBackUp[MainCtrlName] = MainCtrl.children[0].cloneNode(true);
                // 首次进入 ,移除 <页面渲染主控件>
                MainCtrl.removeChild(MainCtrl.children[0]);
                InitSign[MainCtrlName] = true;
            }
            return MainCtrl
        },

        /**
         * [getFunc 获取元素值]
         * @author Seven
         * @date   2020-03-12
         */
        getFunc: function (valElem ,frmData){
            // 是否拥有上传标识 - 判断
            let is_post = (valElem.hasAttribute('post')|| valElem.hasAttribute('post-up') !== undefined);
            is_post = is_post ? true : (valElem.hasAttribute('is-post') !== undefined || valElem.hasAttribute('ispost') !== undefined);
            if(is_post){
                let setKey = valElem.hasAttribute('post-key') ? valElem.getAttribute('post-key') : false;
                setKey = setKey ? setKey.replace(/-/g ,'_').split('.') : valElem.getAttribute('name').replace(/-/g ,'_').split('.');

                // 数据引导区, 处理最后一层 ,生成对应空数组
                let ValFrm = frmData;
                if(setKey.length > 1){
                    for(let j = 0; j < setKey.length - 1; j++)
                        ValFrm = ValFrm[setKey[j]] == undefined ? ValFrm[setKey[j]] = new Object() : ValFrm[setKey[j]];
                }

                // 获取最后一项数据键名
                setKey = setKey[setKey.length - 1];
                // 数据类型分割
                if(ValFrm[setKey] !== undefined) {
                    // 数组类型 [同一键名 ,多次存储形成数组]
                    if(typeof ValFrm[setKey] !== 'object' || typeof ValFrm[setKey] !== 'object'){
                        let value = ValFrm[setKey];
                        ValFrm[setKey] = new Array()
                        ValFrm[setKey].push(value)
                    }
                    ValFrm[setKey].push(valElem.hasAttribute('value') ? valElem.getAttribute('value') : valElem.innerHTML)
                }else{
                    // 普通数据类型
                    ValFrm[setKey] = (valElem.nodeName) == 'SELECT' ? 
                                        (valElem.options[valElem.selectedIndex].value) :
                                        (valElem.hasAttribute('value') ? valElem.getAttribute('value') : valElem.innerHTML);
                }
            }
        },

        /**
         * [setValue 独立元素值保存信息项]
         * @author Seven
         * @date   2020-03-12
         * @message 加入更多的元素TagName进行扩展
         */
        setValue: function (valElem ,value){
            // 选择显示控件 [ 仅控件显示 / 控件值替换显示 ]
            let isExists = valElem.getAttribute('is-exists');
            let isExistsVal = valElem.getAttribute('is-exists-val');
            // 控件类型
            let TagName = valElem.tagName;
            switch(TagName){
                case 'DIV':
                case 'SPAN':
                case 'P':
                    if(isExists    && isExists    != value) valElem.style.display = 'none'
                    if(isExistsVal && isExistsVal != value) valElem.style.display = 'none'
                    if(!isExists   || isExistsVal == value) valElem.innerHTML = value
                    break;
                case 'INPUT':
                case 'SELECT':
                    if(isExists    && isExists    != value) valElem.style.display = 'none'
                    if(isExistsVal && isExistsVal != value) valElem.style.display = 'none'
                    if(!isExists   || isExistsVal == value) valElem.setAttribute('value' ,value)
                    break;
                case 'IMG':
                    if(isExists    && isExists    != value) valElem.style.display = 'none'
                    if(isExistsVal && isExistsVal != value) valElem.style.display = 'none'
                    if(!isExists   || isExistsVal == value) valElem.setAttribute('src' ,value)
                    break;
            }
        },

        /**
         * [SimpleArrayRendering 渲染中,数组单一元素样式简单渲染]
         * @author Seven
         * @date   2020-03-12
         */
        SimpleArrayRendering: function (valElem ,mainData ,key){
            // 内套数组简单循环渲染
            for(let i=0;i < mainData.length;i ++){
                let ArrayElems = valElem.cloneNode(true)
                PrivateClass.setValue(ArrayElems ,mainData[i])
                valElem.parentNode.appendChild(ArrayElems)
            }
        },

        /**
         * [ComplicatedArrayRendering 渲染中,数组多重元素复杂渲染]
         * @author Seven
         * @date   2020-03-12
         */
        ComplicatedArrayRendering: function (rootNode ,classNode ,key ,mainData){
            // 内套数组简单循环渲染
            for(let i=0;i < mainData.length;i ++){
                let FatherNode = classNode.cloneNode(true)

                // 找到对应的组件
                let ArrayElems = PrivateClass.ComplicatedFindChild(FatherNode ,key ,mainData[i])
                rootNode.appendChild(FatherNode)
            }
            // 移除组件元素
            rootNode.removeChild(classNode)
        },

        /**
         * [ComplicatedFindRoot 递归定位元素寻最顶层根]
         * @author Seven
         * @date   2020-03-12
         */
        ComplicatedFindRoot: function (fixedElem){
            let ArrayElems = new Array
            if(fixedElem.parentNode == null){
                return false
            }else{
                ArrayElems.push(fixedElem)
                let tmp = PrivateClass.ComplicatedFindRoot(fixedElem.parentNode)
                if(tmp !== false){
                    ArrayElems.push.apply(ArrayElems ,tmp)
                }
            }
            return ArrayElems
        },

        /**
         * [ComplicatedFind 递归元素内子元素找到目标赋值]
         * @author Seven
         * @date   2020-03-12
         */
        ComplicatedFindChild: function (rootNode ,name ,value){
            let Elements = rootNode.children
            for(let i=0;i < Elements.length;i ++){
                if(Elements[i].getAttribute('name') === name){
                    PrivateClass.setValue(Elements[i] ,value)
                    break
                }else if(Elements[i].hasChildNodes()){
                    PrivateClass.ComplicatedFindChild(Elements[i] ,name ,value)
                }
            }
        },

        /**
         * [Rendering 渲染功能]
         * @author Seven
         * @date   2020-03-12
         */
        Rendering: function (valElem ,MainData){
            let key = valElem.getAttribute('name');
            key = key !== null ? (MainData[key] ? key : (MainData[key.replace(/-/g ,'_')] ? key.replace(/-/g ,'_') : false)) : false;

            // 重新获取最新的数据
            let subGroup = valElem.getAttribute('name') ? valElem.getAttribute('name') : "";
            let subGroupKey = MainData[subGroup] ? subGroup : (MainData[subGroup.replace(/-/g ,'_')] ? subGroup.replace(/-/g ,'_') : false);
            
            // 子项内循环渲染入口
            if(subGroupKey !== false && MainData[subGroupKey] instanceof Array) {
                // 用父级层数区分简单 / 复杂渲染
                let ParentNodeList = PrivateClass.ComplicatedFindRoot(valElem);
                if(ParentNodeList.length < 3){
                    // 简单数组渲染 [以层数控制]
                    let inputElements = PrivateClass.SimpleArrayRendering(valElem ,MainData[subGroupKey] ,subGroupKey)
                    valElem.parentNode.removeChild(valElem)
                }else{
                    let rootNode  = ParentNodeList[ParentNodeList.length - 1]
                    let classNode = ParentNodeList[ParentNodeList.length - 2]

                    // 复杂数组渲染 [样式内套]
                    let inputElements = PrivateClass.ComplicatedArrayRendering(rootNode ,classNode ,subGroupKey ,MainData[subGroupKey])
                }
            }else if(key){
                // 赋值过程
                PrivateClass.setValue(valElem ,MainData[key])
            }
            return valElem
        },
        /**
         * [recurrenceChildren 递归获取控件值]
         * @author Seven
         * @date   2020-03-11
         */
        recurrenceChildren: function(parentChildren ,callback ,MainData = false){
            let tmpParent = parentChildren.cloneNode(true)
            let Elements  = tmpParent.children
            let frmData   = new Object();
            for (let i=0;i < Elements.length;i ++) {
                let valElem = parentChildren.children[i]
                if(valElem.hasChildNodes() && valElem.children.length > 0 && valElem.nodeName !== 'SELECT'){
                    // 内涵子元素 ,递归查询
                    let returnResult = PrivateClass.recurrenceChildren(valElem ,callback ,MainData);
                    if(callback === 'set') returnResult = returnResult
                    frmData = Object.assign(frmData ,returnResult);
                }else{
                    ValFrm = (callback === 'get') ? PrivateClass.getFunc(valElem ,frmData) : PrivateClass.Rendering(valElem ,MainData)
                }
            }
            // 返回元素回调到父级中
            return (callback === 'get') ? frmData : parentChildren
        }
    };

    // 主操作渲染类
    let MainRenderingClass = {
        /** [setElem 页面单独渲染] */
        setElem: function (MainCtrlName ,MainData){
            let MainCtrl = PrivateClass.ControlModel(MainCtrlName);
            if(!(MainCtrl = PrivateClass.ControlModel(MainCtrlName))) return ;
            // 克隆备份数据
            let RenderingCtrlModel = PrivateClass.RenderingBackUp[MainCtrlName].cloneNode(true)

            // 获取渲染结果
            let renderingResult = PrivateClass.recurrenceChildren(RenderingCtrlModel ,'set' ,MainData);
            PrivateClass.ParentBackUp[MainCtrlName].appendChild(renderingResult)
        },
        /** [setGroup 页面循环渲染] */
        setGroup: function (MainCtrlName ,MainData ,overflow = true){
            let MainCtrl = PrivateClass.ControlModel(MainCtrlName);
            if(!(MainCtrl = PrivateClass.ControlModel(MainCtrlName))) return ;

            // 重载清空项
            if(overflow) MainCtrl.innerHTML = "";
            for(let i=0;i < MainData.length;i++){
                let RenderingCtrlModel = PrivateClass.RenderingBackUp[MainCtrlName].cloneNode(true)
                PrivateClass.ParentBackUp[MainCtrlName].appendChild(PrivateClass.recurrenceChildren(RenderingCtrlModel ,'set' ,MainData[i]))
            }
        }
    };

    // 主操作类 [提供外部操作方法]
    let MainOptionClass = {
        get: function (MainCtrlName = false){
            if(!(MainCtrl = PrivateClass.ControlModel(MainCtrlName))) return ;
            return PrivateClass.recurrenceChildren(MainCtrl ,'get');
        } ,
        set: function (MainCtrlName = false ,MainData = false ,overflow = true){
            return MainData instanceof Array ?
                        MainRenderingClass.setGroup(MainCtrlName ,MainData ,overflow) :
                        MainRenderingClass.setElem(MainCtrlName ,MainData);
        }
    };

    return MainOptionClass;
})();

// 单体具体化类
let conver = InputFormInterface;